﻿using System;
using System.Diagnostics;

namespace CommonUtils
{
    /// <summary>
    /// 控制台相关方法
    /// </summary>
    public static class ConsoleUtil
    {
        static bool log = false;

        public static void OpenLog()
        {
            log = true;
        }

        public static void ClearLog()
        {
            FileUtil.Write("", PathUtil.LogPath);
        }

        static string Log(string msg)
        {
            if (log)
                FileUtil.Append(msg, PathUtil.LogPath);
            return msg;
        }


        enum Level
        {
            Info,
            Warining,
            Error
        }

        /// <summary>
        /// 打印开关，只对打印生效，写入照常
        /// 关写入要去LogUtil
        /// </summary>
        public static bool Close = false;

        public static event Action<string> OnWrite;

        private static void Write(Level level, object value, params object[] args)
        {
            if (Close) return;

            //json中的花括号会引发异常，所以加个args判断，一般json不会有args
            var msg = StringUtil.Format(value, args);

            switch (level)
            {
                case Level.Warining:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    break;
                case Level.Error:
                    Console.ForegroundColor = ConsoleColor.Red;
                    break;
                default:
                    Console.ForegroundColor = ConsoleColor.Green;
                    break;
            }

            Console.Write(msg);
            //Console.ResetColor();
            Debug.Write(msg);
            OnWrite?.Invoke(msg);
            Log(msg);
        }

        public static void Write(object value, params object[] args)
        => Write(Level.Info, value, args);

        public static void WriteLine(object value = null, params object[] args)
        => Write(value + StringIdentifier.NewLine + StringIdentifier.NewLine, args);

        private static void WriteLine(Level level, object value = null, params object[] args)
        => Write(level, value + StringIdentifier.NewLine + StringIdentifier.NewLine, args);

        public static void Info(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void Warn(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void Error(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void WriteJson(object value)
        => WriteLine(value.ToJson());

        public static void WriteHello()
        => WriteLine("Hello! " + ApplicationUtil.Name);

        public static void WriteTime()
        => WriteLine(DateTime.Now.FullInfo());

        const string inputCharTip = "Waiting for inputting char...";

        public static char GetInputChar(string tip = inputCharTip)
        {
            WriteLine(tip);
            var ch = Console.ReadKey().KeyChar;
            Log(ch.ToString());
            WriteLine();
            return ch;
        }

        public static char ReadChar(string tip = inputCharTip)
        => GetInputChar(tip);

        public static char GetChar(string tip = inputCharTip)
        => GetInputChar(tip);

        const string inputLineTip = "Waiting for inputting line...";

        public static string GetInputLine(string tip = inputLineTip)
        {
            WriteLine(tip);
            return Log(Console.ReadLine());
        }

        public static string GetInput(string tip = inputLineTip)
        => GetInputLine(tip);

        public static string ReadLine(string tip = inputLineTip)
        => GetInputLine(tip);

        public static string GetLine(string tip = inputLineTip)
        => GetInputLine(tip);

        /// <summary>
        /// 不区分大小写
        /// </summary>
        public static bool YesOrNo()
        {
            while (true)
            {
                WriteLine("Y/N?");
                var key = Console.ReadKey().Key;
                Log(key.ToString());
                WriteLine();
                if (key == ConsoleKey.Y)
                    return true;
                if (key == ConsoleKey.N)
                    return false;
            }
        }

        public static bool InputYesOrNo()
        => YesOrNo();

        /// <summary>
        /// 控制台暂停
        /// </summary>
        public static void Pause(string tip = null, params string[] args)
        {
            if (!string.IsNullOrEmpty(tip))
                WriteLine(tip, args);

            WriteLine("Press enter to continue...");
            Log(Console.ReadLine());
        }

        public static void PauseToExit(string tip = null)
        {
            if (!string.IsNullOrEmpty(tip))
                WriteLine(tip);
            WriteLine("Press enter to exit...");
            Log(Console.ReadLine());
            ApplicationUtil.Close();
        }

        public static void PauseEcpextInputExit(Action<string> action = null)
        {
            if (action != null)
                WriteLine("Input info to process,");
            var input = ReadLine("input exit to step...");

            while (input != "exit")
            {
                action?.Invoke(input);
                input = Log(Console.ReadLine());
            }
        }

        public static void GetLineEcpextExit(Action<string> action = null)
        => PauseEcpextInputExit(action);
    }
}
